"""
Automatic form generation
"""
#from home import webconf as testconf
import sys
from FormKit import Form, Fields
from FormKit.BaseValidatorClasses import ValidatorConverter

class ValidChoice( ValidatorConverter ):
    def __init__(self, values ):
        message = "Choice is not one of the valid options"
        self.values = set(values)
        ValidatorConverter.__init__(self, message)

    def validate(self, value):
        if value in self.values:
            return None
        else:
            return self._getMessage()

def zoom_change( kdict, levels, zkey='zoom' ):
    """
    Changes the zoom level to the next highest or lowest
    """
    step  = 0
    step -= int( 'zoom_in'  in kdict )
    step += int( 'zoom_out' in kdict )
    zoom_value = kdict.get( zkey )
    if zoom_value:
        try:
            zoom_index = levels.index( zoom_value ) + step
            zoom_index = max( [ 0, zoom_index ] )
            zoom_index = min( [ zoom_index, len(levels)-1 ] )
            kdict[zkey] = levels[zoom_index]
        except ValueError, exc:
            # unexpected value, it will be caught at validation
            pass

    return kdict

def pan_view( kdict ):
    """
    Pans the center of the view depending on the parameters
    Mutates the parameter, adds the start, end fields to it
    """
    try:
        center = int( kdict['feature'] )
        zoom_half = int( kdict['zoom']) / 2
        if 'move_left' in kdict:
            center = max( zoom_half, center - zoom_half )
        elif 'move_right' in kdict:
            center += zoom_half
        start = center - zoom_half
        end   = center + zoom_half 
        kdict['start'] = start
        kdict['end']   = end
        kdict['feature'] = (start + end)/2
    except Exception, exc:
        sys.stderr.write('*** pan_view error %s' % exc)
    
    return kdict
    
def add_choices( choice, items):
    "Mutates the choice field, adds the items"
    for key, value in items:
        choice.addChoice( key, value )
    values = [ x[0] for x in items ]
    choice.addValidator( ValidChoice( values ) )    

def main_form( conf ):
    """
    Renders a form
    """
    form      = Form.Form( action="", method="get" )

    # navigation
    feature   = Fields.TextField( 'feature', label='Feature', required=True, attributes=dict(size=8) )
    chrom     = Fields.SelectField( 'chrom', label='Chromosome', required=True )
    zoom      = Fields.SelectField( 'zoom', label='Zoom', required=True )
    plot      = Fields.SelectField( 'plot', label='Plot choice', required=True )
    img_size  = Fields.TextField( 'img_size', label='Image size', required=True, attributes=dict(size=4) )
    min_fit   = Fields.TextField( 'min_fit', label='Minimum Fit', required=True, attributes=dict(size=3) )
    
    # options
    orf_track = Fields.Checkbox( 'orf_track', required=False )
    nuc_track = Fields.Checkbox( 'nuc_track', required=False )

    add_choices( chrom, conf.CHROM_FIELDS) 
    add_choices( zoom,  conf.ZOOM_LEVELS) 
    add_choices( plot,  conf.PLOT_CHOICES) 
   
    # create the form
    for field in ( feature, chrom, zoom, plot, img_size, orf_track, nuc_track, min_fit ):
        form.addField( field )
    
    # default values
    seed = dict( 
        feature = 10000, 
        chrom = conf.CHROM_FIELDS[0][0], 
        zoom  = conf.ZOOM_LEVELS[5][0],
        plot  = conf.PLOT_CHOICES[0][0], 
        img_size = 1000, 
        orf_track = 'True', 
        nuc_track = 'True', 
        min_fit   = 0
    )
    form.seed( seed )
    return form

def test( verbose=0 ):
    "Performs module level testing"
    import doctest
    doctest.testmod( optionflags=doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE, verbose=verbose )

if __name__ == "__main__":
    test()

    """
    data = dict( feature='123', chrom='chr01' )
    form = get_form( testconf )
    
    form.seed( {'chrom':1} )

    #form.process( {} )
    
    print form.values( )
    print form.defaults()

    #print form.values()
    print form.errors()
    print form.isSuccessful()

    #print form.tableDump()
    """